#include "TestApp.h"

#include <QApplication>
#include <QDir>
#include <QFileInfo>
#include <QDebug>
#include <QMessageBox>
#include <QJsonDocument>
#include <QJsonObject>
#include <QByteArray>

TestApp::TestApp(QWidget *parent)
    : QMainWindow(parent)
    , m_centralWidget(new QWidget(this))
    , m_mainLayout(new QVBoxLayout(m_centralWidget))
    , m_screenNameLabel(new QLabel("屏幕名称:", this))
    , m_screenNameEdit(new QLineEdit(this))
    , m_startAppButton(new QPushButton("启动应用", this))
    , m_startCastButton(new QPushButton("开始投屏", this))
    , m_stopCastButton(new QPushButton("停止投屏", this))
    , m_quitAppButton(new QPushButton("关闭应用", this))
    , m_process(new QProcess(this))
    , m_socket(new QLocalSocket(this))
{
    // 设置窗口标题
    setWindowTitle("智林白板投屏测试应用");
    
    // 设置中心窗口部件
    setCentralWidget(m_centralWidget);
    
    // 设置布局
    QHBoxLayout *screenNameLayout = new QHBoxLayout();
    screenNameLayout->addWidget(m_screenNameLabel);
    screenNameLayout->addWidget(m_screenNameEdit);
    
    m_mainLayout->addLayout(screenNameLayout);
    m_mainLayout->addWidget(m_startAppButton);
    m_mainLayout->addWidget(m_startCastButton);
    m_mainLayout->addWidget(m_stopCastButton);
    m_mainLayout->addWidget(m_quitAppButton);
    
    // 设置默认屏幕名称
    m_screenNameEdit->setText("Screen-0");
    
    // 设置按钮状态
    m_startCastButton->setEnabled(false);
    m_stopCastButton->setEnabled(false);
    m_quitAppButton->setEnabled(false);
    
    // 连接信号和槽
    connect(m_startAppButton, &QPushButton::clicked, this, &TestApp::onStartAppClicked);
    connect(m_startCastButton, &QPushButton::clicked, this, &TestApp::onStartCastClicked);
    connect(m_stopCastButton, &QPushButton::clicked, this, &TestApp::onStopCastClicked);
    connect(m_quitAppButton, &QPushButton::clicked, this, &TestApp::onQuitAppClicked);
    
    connect(m_process, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), 
            this, &TestApp::onProcessFinished);
    connect(m_process, &QProcess::errorOccurred, this, &TestApp::onProcessError);
    
    // 设置应用路径
    m_appPath = QDir::currentPath() + "/ZhilinWhiteboard";
    
    // 检查应用是否存在
    QFileInfo fileInfo(m_appPath);
    if (!fileInfo.exists() || !fileInfo.isExecutable()) {
        QMessageBox::warning(this, "警告", "找不到智林白板投屏应用或该应用不可执行。\n"
                                        "请确保应用程序在当前目录下，并且具有可执行权限。\n"
                                        "应用路径: " + m_appPath);
    }
    
    // 设置窗口大小
    resize(400, 200);
}

TestApp::~TestApp()
{
    // 如果进程正在运行，则终止它
    if (m_process->state() != QProcess::NotRunning) {
        m_process->terminate();
        m_process->waitForFinished(3000);
        if (m_process->state() != QProcess::NotRunning) {
            m_process->kill();
        }
    }
    
    // 如果套接字已连接，则断开连接
    if (m_socket->state() == QLocalSocket::ConnectedState) {
        m_socket->disconnectFromServer();
    }
}

void TestApp::onStartAppClicked()
{
    // 如果进程已经在运行，则返回
    if (m_process->state() != QProcess::NotRunning) {
        QMessageBox::information(this, "提示", "智林白板投屏应用已经在运行中。");
        return;
    }
    
    // 获取屏幕名称
    QString screenName = m_screenNameEdit->text().trimmed();
    
    // 设置启动参数
    QStringList arguments;
    if (!screenName.isEmpty()) {
        arguments << "--startMainScreenName=" + screenName;
    }
    
    // 启动应用
    qDebug() << "启动应用:" << m_appPath << "参数:" << arguments;
    m_process->start(m_appPath, arguments);
    
    // 等待应用启动
    if (!m_process->waitForStarted(5000)) {
        QMessageBox::critical(this, "错误", "无法启动智林白板投屏应用。\n错误信息: " + m_process->errorString());
        return;
    }
    
    // 更新按钮状态
    m_startAppButton->setEnabled(false);
    m_startCastButton->setEnabled(true);
    m_stopCastButton->setEnabled(false);
    m_quitAppButton->setEnabled(true);
    
    QMessageBox::information(this, "提示", "智林白板投屏应用已启动。");
}

void TestApp::onStartCastClicked()
{
    // 获取屏幕名称
    QString screenName = m_screenNameEdit->text().trimmed();
    
    // 创建命令对象
    QJsonObject command;
    command["command"] = "start-cast";
    command["name"] = screenName;
    
    // 发送命令
    if (sendCommand(command)) {
        // 更新按钮状态
        m_startCastButton->setEnabled(false);
        m_stopCastButton->setEnabled(true);
        
        QMessageBox::information(this, "提示", "已发送开始投屏命令。");
    }
}

void TestApp::onStopCastClicked()
{
    // 创建命令对象
    QJsonObject command;
    command["command"] = "stop-cast";
    command["name"] = "";
    
    // 发送命令
    if (sendCommand(command)) {
        // 更新按钮状态
        m_startCastButton->setEnabled(true);
        m_stopCastButton->setEnabled(false);
        
        QMessageBox::information(this, "提示", "已发送停止投屏命令。");
    }
}

void TestApp::onQuitAppClicked()
{
    // 创建命令对象
    QJsonObject command;
    command["command"] = "quit-app";
    command["name"] = "";
    
    // 发送命令
    if (sendCommand(command)) {
        // 更新按钮状态
        m_startAppButton->setEnabled(true);
        m_startCastButton->setEnabled(false);
        m_stopCastButton->setEnabled(false);
        m_quitAppButton->setEnabled(false);
        
        QMessageBox::information(this, "提示", "已发送关闭应用命令。");
    }
}

void TestApp::onProcessFinished(int exitCode, QProcess::ExitStatus exitStatus)
{
    qDebug() << "应用进程已结束，退出代码:" << exitCode << "退出状态:" << exitStatus;
    
    // 更新按钮状态
    m_startAppButton->setEnabled(true);
    m_startCastButton->setEnabled(false);
    m_stopCastButton->setEnabled(false);
    m_quitAppButton->setEnabled(false);
    
    // 如果套接字已连接，则断开连接
    if (m_socket->state() == QLocalSocket::ConnectedState) {
        m_socket->disconnectFromServer();
    }
    
    QMessageBox::information(this, "提示", "智林白板投屏应用已退出。");
}

void TestApp::onProcessError(QProcess::ProcessError error)
{
    qDebug() << "应用进程错误:" << error << "错误信息:" << m_process->errorString();
    
    // 更新按钮状态
    m_startAppButton->setEnabled(true);
    m_startCastButton->setEnabled(false);
    m_stopCastButton->setEnabled(false);
    m_quitAppButton->setEnabled(false);
    
    QMessageBox::critical(this, "错误", "智林白板投屏应用发生错误。\n错误信息: " + m_process->errorString());
}

bool TestApp::sendCommand(const QJsonObject &command)
{
    // 如果套接字未连接，则连接到服务器
    if (m_socket->state() != QLocalSocket::ConnectedState) {
        m_socket->connectToServer("ZhilinWhiteboardSocketServer");
        if (!m_socket->waitForConnected(1000)) {
            QMessageBox::critical(this, "错误", "无法连接到智林白板投屏应用。\n错误信息: " + m_socket->errorString());
            return false;
        }
    }
    
    // 将命令转换为JSON文档
    QJsonDocument doc(command);
    QByteArray data = doc.toJson(QJsonDocument::Compact);
    
    // 发送数据
    qint64 bytesWritten = m_socket->write(data);
    if (bytesWritten != data.size()) {
        QMessageBox::critical(this, "错误", "发送命令时出错。\n只写入了 " + 
                             QString::number(bytesWritten) + " 字节，应写入 " + 
                             QString::number(data.size()) + " 字节。");
        return false;
    }
    
    // 等待数据发送完成
    if (!m_socket->waitForBytesWritten(1000)) {
        QMessageBox::critical(this, "错误", "发送命令超时。\n错误信息: " + m_socket->errorString());
        return false;
    }
    
    qDebug() << "已发送命令:" << QString::fromUtf8(data);
    return true;
}
